import Vue from 'vue'
import router from '@/router/index.js'
export default {
  install(Vue, options) {
    //路由返回
    Vue.prototype.backRouter = function () {
      router.go(-1)
    }
    //路由跳转
    Vue.prototype.comeRouter = function (params) {
      if (params.constructor == Object) {
        router.push({
          path: params.path,
          query: params.query
        })
      } else {
        router.push({
          path: params
        })
      }
    }

    //空格处理
    Vue.prototype.trim = function (s) {
      return trimRight(s)
    }

    //分页数
    Vue.prototype.hisPageSizes = function (count, pageSize = 10) {
      let pagesList = []
      let frequency = parseInt(count / pageSize) + 1
      for (let i = 1; i <= frequency; i++) {
        pagesList.push(pageSize * i)
      }
      return pagesList
    }

    // 日期格式化   --> 2018-10-08
    Vue.prototype.formatDate = (date) => {
      if( !date ){
        return false;
      }
      const year = date.getFullYear()
      const month = date.getMonth() + 1
      const day = date.getDate()
      return [year, month, day]
        .map(n => {
          n = n.toString()
          return n[1] ? n : '0' + n
        })
        .join('-')
    }
    

    // 日期+时间格式化  --> 2018-10-08 12:00:00
    Vue.prototype.formatDateTime = (date) => {
      if( !date ){
        return false;
      }
      const year = date.getFullYear()
      const month = date.getMonth() + 1
      const day = date.getDate()
      const hour = date.getHours()
      const minute = date.getMinutes()
      const second = date.getSeconds()
      return year + '-' + (month >= 10 ? month : '0' + month) + '-' +
        (day >= 10 ? day : '0' + day) +
        ' ' + (hour >= 10  ? hour : '0' + hour) +
        ':' + (minute >= 10 ? minute : '0' + minute) + ':' +
        (second >= 10 ? second : '0' + second)
    }


    // 时间格式化  --> 12:00:00
    Vue.prototype.formatTime = (date) => {
      if( !date ){
        return false;
      }
      const hour = date.getHours()
      const minute = date.getMinutes()
      const second = date.getSeconds()
      retuen (hour >= 10  ? hour : '0' + hour) +
      ':' + (minute >= 10 ? minute : '0' + minute) + ':' +
      (second >= 10 ? second : '0' + second)
    }
    //获取近一周、近一月、近半年等时间 days - 天数 正整数 如近三十天 days传30
    Vue.prototype.getDateToDate = (days) => {
      if (IsInteger(days)) {
        console.warn("日期不是正整数")
        return {
          dateType: false
        }  
      } else {
        let startDate = new Date();
        let endDate = new Date();
        startDate.setTime(startDate.getTime() - 3600 * 1000 * 24 * days);
        startDate = formatDate(startDate);
        endDate = formatDate(endDate);
        return {
          dateType: true,
          startDate: startDate,
          endDate: endDate,
        }
      }
    }

    //两个时间日期时间差 -- 天数
    Vue.prototype.calculatedDays = date => {
      return (new Date(date[1]) - new Date(date[0])) / (1000 * 60 * 60 * 24)
    }

    // 开始时间和结束时间校验 --- 精确到秒
    Vue.prototype.compareTime = (start, end) => {
      let startTime = new Date(start).getTime()
      let endTime = new Date(end).getTime()
      if (startTime >= endTime) {
        return false
      } else {
        return true
      }
    }

    // 开始时间和结束时间校验  -- 精确到天
    Vue.prototype.compareDay = (start, end) => {
        if( !start || !end ){
            return true
        }
        let startTime = formatDate(new Date(start))
        let endTime = formatDate(new Date(end))
        if (startTime >= endTime) {
          return false
        } else {
          return true
        }
      }

    // 清除校验
    Vue.prototype.clearValidate = (value, el) => {
      if (value == '' || value == null) {
        el.clearValidate()
      }
    };

    // 获取按钮级权限
    Vue.prototype.getBtnAuth = function () {
      let path = this.$route.path
      path = path.substring(1)
      const btnList = JSON.parse(localStorage.getItem('user')).btnList
      const res = {}
      if (btnList && btnList.length > 0) {
        for (let i = 0; i < btnList.length; i++) {
          const item = btnList[i]
          if (item[path]) {
            Object.assign(res, item[path])
          }
        }
      }
      return Object.keys(res) || []
    };
    //加载处理
    Vue.prototype.axiosLoading = function (str = '数据请求中...') {
      return this.$loading({
        lock: true,
        text: str,
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    };

     

    //遍历私有对象过滤null或undefined
    Vue.prototype.traversalObject = function (object) {
      for (const key in object) {
        if (object.hasOwnProperty(key)) {
          const element = object[key];
          if (element != null && element != undefined && element instanceof Object) {
            this.traversalObject(element);
          } else if (element instanceof Array) {
            this.traversalArray(element);
          } else if (element == null || element == undefined) {
            object[key] = '';
          }
        }
      }
      return object;
    };
    //遍历数组处理数组内的对象
    Vue.prototype.traversalArray = function (array) {
      if (array instanceof Array) {
        array.map(item => {
          if (item instanceof Array) {
            this.traversalArray(item);
          } else if (item instanceof Object) {
            this.traversalObject(item);
          }
        })
      } else {
        throw new Error('array不是一个数组');
      }
    };
    //剔除数组中指定项
    Vue.prototype.removeObjFromArrayByKeyValue = (arr, key, value) => {
      if (arr instanceof Array) {
        arr.map(item => {
          if (item[key] == value) {
            let index = arr.indexOf(item)
            arr.splice(index, 1);
          }
        })
        return arr
      } else {
        this.$message({
          message: "参数必须为数组类型",
          type: "warning"
        });
      }
    };
    //根据开始时间和结束时间 返回中间的每一天
    Vue.prototype.formatEveryDay = function (start, end) {
      let dateList = [];
      var startTime = getDate(start);
      var endTime = getDate(end);
      while (endTime.getTime() - startTime.getTime() >= 0) {
        var year = startTime.getFullYear();
        var month =
          startTime.getMonth() + 1 < 10 ?
          "0" + (startTime.getMonth() + 1) :
          startTime.getMonth() + 1;
        var day =
          startTime.getDate().toString().length == 1 ?
          "0" + startTime.getDate() :
          startTime.getDate();
        dateList.push(year + "-" + month + "-" + day);
        startTime.setDate(startTime.getDate() + 1);
      }
      return dateList;
    };
    //数组重复或数组对象重复判断
    Vue.prototype.arrayRepet = (arr, key, attr) => {
      let temp = []; //临时存储
      let tempObj = {}; //临时对象
      let repeatArr = []; //重复项
      let objState = false; //对象状态
      let strState = false; //字符串状态
      arr.map((item, index) => {
        //对象
        if (utility.isObj(item)) {
          objState = true;
          //key是对象时
          if (utility.isObj(item[key])) {
            if (!tempObj[item[key][attr]]) {
              temp.push(item);
              tempObj[[item[key][attr]]] = true;
            } else {
              repeatArr.push(index);
            }
          } else { //key为普通值
            if (item[key] != '' && item[key] != 'undefined') {
              if (!tempObj[item[key]]) {
                temp.push(item);
                tempObj[[item[key]]] = true;
              } else {
                repeatArr.push(index);
              }
            }
          }
          if (objState && strState) {
            throw Error('数组不支持混合类型普通类型和对象类型！');
          }

        } else if (utility.isArray(item)) {
          throw Error('暂不支持二维数组');
        } else { //普通值
          strState = true;
          if (!tempObj[item]) {
            temp.push(item);
            tempObj[item] = true;
          } else {
            repeatArr.push(index);
          }
          if (objState && strState) {
            throw Error('数组不支持混合类型普通类型和对象类型！');
          }
        }
      })
      return repeatArr;
    };
    //整合数组对象的code
    Vue.prototype.getArrCode = function (array, key) {
      let arr = [];
      array.map(item => {
        arr.push(item[key]);
      });
      return arr;
    };
    //判断数组对象中的某个键是否重复
    Vue.prototype.isArrObjSame = function (array, key) {
      let arr = this.getArrCode(array, key);
      arr = arr.sort();
      for (var i = 0; i < arr.length - 1; i++) {
        if (arr[i] == arr[i + 1]) {
          return true;
        }
      }
      return false;
    };

    //数组对象 根据key 去重
    Vue.prototype.arrayUnique = function (arr, name) {
      var hash = {};
      return arr.reduce(function (item, next) {
        hash[next[name]] ? '' : hash[next[name]] = true && item.push(next);
        return item;
      }, []);
    };


    //判断输入必须为正整数
    Vue.prototype.checkNumIsInteger = (value) => {
      if (value != '' && value != null) {
        if (!/^\+?[1-9][0-9]*$/.test(value)) {
          return true
        } else {
          return false;
        }
      } else {
        return true;
      }
    };


    //两个数组对象比较根据key取出不同项
    Vue.prototype.getDiffArr = function (array1, array2, key) {
      if (!utility.isArray(array1) || !utility.isArray(array2)) {
        console.warn('getDiffArr方法的参数不是数组！')
      }
      if (!key) {
        console.warn('getDiffArr方法的参数key为空！')
      }
      let result1 = []; //删除
      let result2 = []; //新增
      for (var i = 0; i < array1.length; i++) {
        var obj = array1[i];
        var num = obj[key];
        var isExist = false;
        for (var j = 0; j < array2.length; j++) {
          var aj = array2[j];
          var n = aj[key];
          if (n == num) {
            isExist = true;
            break;
          }
        }
        if (!isExist) {
          result1.push(obj);
        }
      }
      for (var i = 0; i < array2.length; i++) {
        var obj = array2[i];
        var num = obj[key];
        var isExist = false;
        for (var j = 0; j < array1.length; j++) {
          var aj = array1[j];
          var n = aj[key];
          if (n == num) {
            isExist = true;
            break;
          }
        }
        if (!isExist) {
          result2.push(obj);
        }
      }
      return {
        delArr: result1,
        addArr: result2
      }
    };
    
    //对象拷贝---深拷贝
    Vue.prototype.copyObject = (object) => {
      return JSON.parse(JSON.stringify(object));
    };

    /**
     * 深拷贝
     * 
    */
     Vue.prototype.deepCopy = function(obj){
      if( obj.constructor !== Array && obj.constructor !== object ){
        return obj
      }else{
         let targetObj = obj.constructor === Array ? [] : {};
         for( let i in obj ){
         if( typeof obj[i]  === 'object' ){
           targetObj[i] = obj[i].constructor === Array ? [] : {}; 
           targetObj[i] = this.deepCopy(obj[i])
         }else{
           targetObj[i]=obj[i] 
         }
         }
      }
       return targetObj
     }

    /** 
     * object1 type:object  des:接收对象
     * object2 type:object  des:数据对象
     * 
     */
    //两个对象相互赋值
    Vue.prototype.listAssign = function (object1, object2) {
      let object1Keys = Object.keys(object1);
      object1Keys.forEach(key => {
        if (utility.isObj(object1[key]) && utility.isObj(object2[key])) {
          this.listAssign(object1[key], object2[key])
        } else {
          object1[key] = object2[key] || object1[key];
        }
      })
      return object1;
    };
    //统计数组内重复的次数
    Vue.prototype.numStatistics = function (array, key) {
      let resMap = {}; //存储统计
      //类型
      if (!utility.isArray(array)) {
        throw Error('参数不是一个数组');
        return;
      };
      if (!key) {
        throw Error('参数异常');
      }
      for (let i = 0; i < array.length; i++) {
        let outItem = array[i];
        if (outItem[key] == '' || outItem[key] == undefined) {
          // throw Error('对象属性值不能为空！')
          // outItem[key] = 'default';
          break;
        }
        //存在
        if (resMap[outItem[key]]) {
          resMap[outItem[key]].count++;
          continue; //结束
        };
        for (let j = i + 1; j < array.length; j++) {
          let innerItem = array[j];
          if (outItem[key] === innerItem[key]) {
            resMap[outItem[key]] = {
              data: outItem,
              count: 1
            }
            break; //结束
          }
        }
      };
      return resMap;
    };
    //判断某个字符串或数字在一个数组内
    Vue.prototype.deleteArrayIndex = function (array, item) {
      if (array instanceof Array) {
        let index = -1;
        let arr = [];
        array.map((v, i) => {
          if (v == item) {
            index = i;
          }
        })
        if (array.length == 1 && index == 0) {
          return [];
        }
        return arr = index == -1 ? array : array.slice(0, index).concat(array.slice(parseInt(index, 10) + 1));
      } else {
        throw Error('参数不合法，deleteArrayIndex参数不是一个数组！')
      }
    };
    //根据数组对象的属性值 是否一致合并数组对象
    Vue.prototype.reMerge = function (arr, type, list) {
      let map = {},
        dest = [];
      for (var i = 0; i < arr.length; i++) {
        var arri = arr[i];
        if (!map[arri[type]]) {
          dest.push({
            type: arri[type],
            list: arri[list],
          });
          map[arri[type]] = arri;
        } else {
          for (var j = 0; j < dest.length; j++) {
            var dj = dest[j];
            if (dj.type == arri[type]) {
              dj.list = dj.list.concat(arri[list]);
              break;
            }
          }
        }
      };
      return dest
    };

    /** 精准计算浮点数 
     * num1 , num2  要计算的浮点数参数
     * type     计算的类型  add-加  sub-减  mul-乘  div-除
     */
    Vue.prototype.floatNumber = function (num1, num2, type) {
      switch (type) {
        case 'add':
          return floatAdd(num1, num2);
          break;
        case 'sub':
          return floatSub(num1, num2)
          break;
        case 'mul':
          return floatMul(num1, num2)
          break;
        case 'div':
          return floatDiv(num1, num2)
          break;
        default:
          break;
      }
    };
    /*
     * websocket长链接
     * websocket 连接对象
     * socketOff 连接状态
     * backendData 数据推送
     * lockReconnect 重连状态
     * timeout 心跳间隔
     * timeoutObj 心跳定时
     * serverTimeoutObj 服务器定时
     */
    let thats = this;
    Vue.prototype.webSocketConnect = {
      websocket: null, //连接对象
      socketOff: false, //连接状态
      backendData: null, //返回数据
      lockReconnect: false, //重连状态
      timeout: 60000, //60秒
      timeoutObj: null,
      serverTimeoutObj: null,
      reset() { //清除所有定时器
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
      },
      start() {
        this.timeoutObj = setTimeout(() => {
          this.serverTimeoutObj = setTimeout(() => { //如果超过一定时间还没重置，说明后端主动断开了
            this.websocket.close(); //如果onclose会执行reconnect，我们执行self.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次

          }, this.timeout)
        }, this.timeout)
      },
      //创建连接
      creatWebsocket(url, flag) {
        //判断当前浏览器是否支持WebSocket
        if ('WebSocket' in window) {
          try {
            this.websocket = new WebSocket(url);
            this.socketOff = true;
            this.initWebsocket(url, flag);
          } catch (e) {
            this.reconnect(url);
          }
        } else {
          alert('浏览器不支持websocket')
        }
      },
      //初始化连接
      initWebsocket(url, flag) {
        //连接发生错误的回调方法
        this.websocket.onerror = (event) => {
          this.reconnect(url);
        };
        //建立连接成功的回调方法
        this.websocket.onopen = (event) => {
          console.log('连接成功', event);
          this.reset().start();
          // 如果重连 重发消息给后端
          // if (flag) bus.$emit('sendVisitMessage')

        };
        //断开连接
        this.websocket.onclose = (event) => {

          if (this.socketOff) {
            this.reconnect(url, true);
            console.log('连接异常断开了---重新链接')
          } else {
            console.log('人为断开不再连接')
          }
        };
      },
      //发送
      connectSend(obj) {
        this.websocket.send(JSON.stringify(obj));
        //接收到消息的回调方法
        return this.websocket.onmessage = (event) => {

          this.backendData = JSON.parse(event.data);
          // bus.$emit('updatabackendData', this.backendData)

          this.reset().start();

          return this.backendData;

        }
      },
      //重新连接
      reconnect(url, flag) {
        //有连接 return
        if (this.lockReconnect) return;
        this.lockReconnect = true;
        setTimeout(() => {

          this.creatWebsocket(url, flag); //连接
          this.lockReconnect = false; //连接成功状态false

        }, 1000)
      },
      //关闭连接
      closeWebsocket(done) {
        this.websocket.close();
        this.socketOff = false;
        this.websocket = null; //连接对象
        this.backendData = null; //返回数据
        this.lockReconnect = false; //重连状态
      }
    }

  }
}
//正整数判断 供common.js中调用
function IsInteger(value) {
  if (value != '' && value != null) {
    if (!/^\+?[1-9][0-9]*$/.test(value)) {
      return true
    } else {
      return false;
    }
  } else {
    return true;
  }
};
// 日期格式化   供common.js中调用
function formatDate(date) {
  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()
  return [year, month, day]
    .map(n => {
      n = n.toString()
      return n[1] ? n : '0' + n
    })
    .join('-')
}



//日期格式化
function getDate(datestr) {
  var temp = datestr.split("-");
  var date = new Date(temp[0], temp[1] - 1, temp[2]);
  return date;
}

//去掉空格
function trimStr(s) {
  // if (s == null) {
  //   return "";
  // }
  // var whitespace = new String(" \t\n\r");
  // var str = new String(s);
  // if (whitespace.indexOf(str.charAt(0)) != -1) {
  //   var j = 0,
  //     i = str.length;
  //   while (j < i && whitespace.indexOf(str.charAt(j)) != -1) {
  //     j++;
  //   }
  //   str = str.substring(j, i);
  // }
  // return str;
  return s.replace(/(^\s*)|(\s*$)/g, '')
}

//js 加法计算
//返回值：arg1加arg2的精确结果
function floatAdd(arg1, arg2) {
  var r1, r2, m;
  try {
    r1 = arg1.toString().split(".")[1].length
  } catch (e) {
    r1 = 0
  }
  try {
    r2 = arg2.toString().split(".")[1].length
  } catch (e) {
    r2 = 0
  }
  m = Math.pow(10, Math.max(r1, r2));
  return (arg1 * m + arg2 * m) / m;
}

//js 减法计算
//返回值：arg1减arg2的精确结果
function floatSub(arg1, arg2) {
  var r1, r2, m, n;
  try {
    r1 = arg1.toString().split(".")[1].length
  } catch (e) {
    r1 = 0
  }
  try {
    r2 = arg2.toString().split(".")[1].length
  } catch (e) {
    r2 = 0
  }
  m = Math.pow(10, Math.max(r1, r2));
  //动态控制精度长度  
  n = (r1 >= r2) ? r1 : r2;
  return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

//js 乘法函数
//返回值：arg1乘以arg2的精确结果
function floatMul(arg1, arg2) {
  var m = 0,
    s1 = arg1.toString(),
    s2 = arg2.toString();
  try {
    m += s1.split(".")[1].length
  } catch (e) {}
  try {
    m += s2.split(".")[1].length
  } catch (e) {}
  return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}

//js 除法函数
//返回值：arg1除以arg2的精确结果
function floatDiv(arg1, arg2) {
  var t1 = 0,
    t2 = 0,
    r1, r2;
  try {
    t1 = arg1.toString().split(".")[1].length
  } catch (e) {}
  try {
    t2 = arg2.toString().split(".")[1].length
  } catch (e) {}

  r1 = Number(arg1.toString().replace(".", ""));

  r2 = Number(arg2.toString().replace(".", ""));
  return (r1 / r2) * Math.pow(10, t2 - t1);
}

//去掉右边的空白
function trimRight(s) {
  if (s == null) return ''
  var whitespace = new String(' \t\n\r')
  var str = new String(s)
  if (whitespace.indexOf(str.charAt(str.length - 1)) != -1) {
    var i = str.length - 1
    while (i >= 0 && whitespace.indexOf(str.charAt(i)) != -1) {
      i--
    }
    str = str.substring(0, i + 1)
  }
  return str
}

var gettype = Object.prototype.toString

var utility = {

  isObj: function (o) {

    return gettype.call(o) == "[object Object]";

  },

  isArray: function (o) {

    return gettype.call(o) == "[object Array]";

  },

  isNULL: function (o) {

    return gettype.call(o) == "[object Null]";

  }

}
